package com.itheima.utlis;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * ClassName:Logger
 * Package:com.itheima.utlis
 * Description:用于记录日志的工具类，它提供了公共的代码
 * Date:2020/2/24 16:07
 * User: snow
 */
@Component("logger")
@Aspect//表示当前类是一个切面类
public class Logger {
	@Pointcut("execution(* *.*.service.impl.*.*(..))")
	private void pt1(){}
	/**
	 * 前置通知
	 */
	@Before("pt1()")
	public void beforePrintLog() {
		System.out.println("前置通知 printLog of Logger Class is star writing Log.......");
	}

	/**
	 * 后置通知
	 */
	@AfterReturning("pt1()")
	public void afterReturningPrintLog() {
		System.out.println("后置通知 printLog of Logger Class is star writing Log.......");
	}

	/**
	 * 异常通知
	 */
	@AfterThrowing("pt1()")
	public void afterThrowinigPrintLog() {
		System.out.println("异常通知 printLog of Logger Class is star writing Log.......");
	}

	/**
	 * 最终通知
	 */
	@After("pt1()")
	public void afterPrintLog() {
		System.out.println("最终通知 printLog of Logger Class is star writing Log.......");
	}

	/**
	 * 环绕通知
	 * 问题：
	 *     配置环绕通知后，切入点方法没有执行，通知方法执行了
	 *  解决办法：
	 *      Spring框架为我们提供了一个接口，ProceedingJoinPoint
	 *      该接口有一个方法proceed()，此方法相当于明确调用切入点方法
	 *      该接口可以作为环绕通知的方法参数，在程序执行时，Spring框架会为我们提供该接口的实现类供我们使用
	 *  Spring中的环绕通知
	 *          它是Spring框架为我们提供的一种可以在代码中手动控制增强方法在何时执行的方法
	 */
	@Around("pt1()")
	public Object aroundPrintLog(ProceedingJoinPoint proceedingJoinPoint) {
		Object returnValue = null;
		try{
			Object[] args = proceedingJoinPoint.getArgs();//得到方法执行所需的参数
			System.out.println("环绕通知 前置printLog of Logger Class is star writing Log.......");
			proceedingJoinPoint.proceed(args);//明确调用业务层方法（切入点方法）
			System.out.println("环绕通知 后置printLog of Logger Class is star writing Log.......");
			return returnValue;
		}catch (Throwable t){
			System.out.println("环绕通知 异常printLog of Logger Class is star writing Log.......");
			throw  new RuntimeException(t);
		}finally {
			System.out.println("环绕通知 最终printLog of Logger Class is star writing Log.......");
		}


	}
}
